From 25f6da5e897a113a781d5575723afa4d56cddd88 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 8 Jul 2020 16:58:11 +0100 Subject: [PATCH] Have GtkWidget implement GtkAccessible Each widget type has an accessible role associated to its class, as roles cannot change during the life time of a widget instance. Each widget is also responsible for creating an ATContext, to proxy state changes to the underlying accessibility infrastructure. --- gtk/gtkwidget.c | 48 +++++++++++++++++++++++++++++++++++++++++- gtk/gtkwidget.h | 4 ++++ gtk/gtkwidgetprivate.h | 5 +++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 9013ad6661..e1bed207f4 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -27,7 +27,7 @@ #include "gtkwidgetprivate.h" #include "gtkaccelgroupprivate.h" -#include "gtkaccessible.h" +#include "gtkaccessibleprivate.h" #include "gtkactionobserverprivate.h" #include "gtkapplicationprivate.h" #include "gtkbuildable.h" @@ -756,6 +756,8 @@ gtk_widget_base_class_init (gpointer g_class) g_object_unref (shortcut); } } + + priv->accessible_role = GTK_ACCESSIBLE_ROLE_WIDGET; } static void @@ -7000,6 +7002,8 @@ gtk_widget_dispose (GObject *object) gtk_layout_manager_set_widget (priv->layout_manager, NULL); g_clear_object (&priv->layout_manager); + g_clear_object (&priv->at_context); + priv->visible = FALSE; if (_gtk_widget_get_realized (widget)) gtk_widget_unrealize (widget); @@ -8053,9 +8057,29 @@ gtk_widget_set_vexpand_set (GtkWidget *widget, /* * GtkAccessible implementation */ + +static GtkATContext * +gtk_widget_accessible_get_at_context (GtkAccessible *accessible) +{ + GtkWidget *self = GTK_WIDGET (accessible); + GtkWidgetPrivate *priv = gtk_widget_get_instance_private (self); + + if (priv->at_context == NULL) + { + GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (self); + GtkWidgetClassPrivate *class_priv = widget_class->priv; + + priv->at_context = + gtk_at_context_create (class_priv->accessible_role, accessible); + } + + return priv->at_context; +} + static void gtk_widget_accessible_interface_init (GtkAccessibleInterface *iface) { + iface->get_at_context = gtk_widget_accessible_get_at_context; } /* @@ -12085,3 +12109,25 @@ gtk_widget_update_orientation (GtkWidget *widget, gtk_widget_remove_css_class (widget, GTK_STYLE_CLASS_HORIZONTAL); } } + +/** + * gtk_widget_class_set_accessible_role: + * @widget_class: a #GtkWidgetClass + * @accessible_role: the #GtkAccessibleRole used by the @widget_class + * + * Sets the accessible role used by the given #GtkWidget class. + * + * Different accessible roles have different states, and are rendered + * differently by assistive technologies. + */ +void +gtk_widget_class_set_accessible_role (GtkWidgetClass *widget_class, + GtkAccessibleRole accessible_role) +{ + GtkWidgetClassPrivate *priv; + + g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class)); + + priv = widget_class->priv; + priv->accessible_role = accessible_role; +} diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index c53198e0f9..fb4d13d5c7 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -977,6 +977,10 @@ void gtk_widget_action_set_enabled (GtkWidget *widget, gboolean enabled); +GDK_AVAILABLE_IN_ALL +void gtk_widget_class_set_accessible_role (GtkWidgetClass *widget_class, + GtkAccessibleRole accessible_role); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkWidget, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRequisition, gtk_requisition_free) diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index be51038ade..60e53705c0 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -28,6 +28,7 @@ #include "gtkwidget.h" #include "gtkactionmuxerprivate.h" +#include "gtkatcontextprivate.h" #include "gtkcsstypesprivate.h" #include "gtkeventcontrollerprivate.h" #include "gtklistlistmodelprivate.h" @@ -191,6 +192,9 @@ struct _GtkWidgetPrivate /* Tooltip */ char *tooltip_markup; char *tooltip_text; + + /* Accessible context */ + GtkATContext *at_context; }; typedef struct @@ -207,6 +211,7 @@ struct _GtkWidgetClassPrivate GQuark css_name; GType layout_manager_type; GtkWidgetAction *actions; + GtkAccessibleRole accessible_role; }; void gtk_widget_root (GtkWidget *widget); -- 2.30.2